package com.pranavnegandhi;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;

public class PuzzleView extends View
{
	private static final String TAG = "com.pranavnegandhi.sudoku.PuzzleView";
	
	private Game game;
	
	private float tileWidth;
	
	private float tileHeight;
	
	private int selX;
	
	private int selY;
	
	private final Rect selRect = new Rect();
	
	public PuzzleView(Context context)
	{
		super(context);
		
		game = (Game)context;
		setFocusable(true);
		setFocusableInTouchMode(true);
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		switch (keyCode)
		{
		case KeyEvent.KEYCODE_DPAD_UP:
			select(selX, selY - 1);
			break;
			
		case KeyEvent.KEYCODE_DPAD_DOWN:
			select(selX, selY + 1);
			break;
			
		case KeyEvent.KEYCODE_DPAD_LEFT:
			select(selX - 1, selY);
			break;
			
		case KeyEvent.KEYCODE_DPAD_RIGHT:
			select(selX + 1, selY);
			break;
			
		default:
			return super.onKeyDown(keyCode, event);
		}
		
		return true;
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event)
	{
		if (MotionEvent.ACTION_DOWN != event.getAction())
			return super.onTouchEvent(event);
		
		select((int)(event.getX() / tileWidth), (int)(event.getY() / tileHeight));
		
		return true;
	}
	
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh)
	{
		tileWidth = w / 9f;
		tileHeight = h / 9f;
		getRect(selX, selY, selRect);
		
		Log.i(PuzzleView.TAG, "onSizeChanged tileWidth " + tileWidth + " tileHeight " + tileHeight);
		super.onSizeChanged(w, h, oldw, oldh);
	}
	
	@Override
	protected void onDraw(Canvas canvas)
	{
		int backgroundcolor = 0xff0000 >>> (8 * game.getDifficulty());
		
		super.onDraw(canvas);
		
		Paint backgroundPaint = new Paint();
		backgroundcolor = 0xff000000 | backgroundcolor;
		backgroundPaint.setColor(backgroundcolor);
		canvas.drawRect(0, 0, getWidth(), getHeight(), backgroundPaint);
		
		Paint borderHighlightPaint = new Paint();
		borderHighlightPaint.setColor(getResources().getColor(R.color.border_highlight));
		Paint borderDarkPaint = new Paint();
		borderDarkPaint.setColor(getResources().getColor(R.color.border_dark));
		Paint borderLightPaint = new Paint();
		borderLightPaint.setColor(getResources().getColor(R.color.border_light));
		
		for (int i = 0; i < 9; i++)
		{
			canvas.drawLine(0, i * tileHeight, getWidth(), i * tileHeight, borderLightPaint);
			canvas.drawLine(0, i * tileHeight + 1, getWidth(), i * tileHeight + 1, borderHighlightPaint);
			canvas.drawLine(i * tileWidth, 0, i * tileWidth, getHeight(), borderLightPaint);
			canvas.drawLine(i * tileWidth + 1, 0, i * tileWidth + 1, getHeight(), borderHighlightPaint);
		}
		
		for (int i = 0; i < 9; i++)
		{
			if (i % 3 != 0)
				continue;
			
			canvas.drawLine(0, i * tileHeight, getWidth(), i * tileHeight, borderDarkPaint);
			canvas.drawLine(0, i * tileHeight + 1, getWidth(), i * tileHeight + 1, borderHighlightPaint);
			canvas.drawLine(i * tileWidth, 0, i * tileWidth, getHeight(), borderDarkPaint);
			canvas.drawLine(i * tileWidth + 1, 0, i * tileWidth + 1, getHeight(), borderHighlightPaint);
		}
		
		Paint foreground = new Paint(Paint.ANTI_ALIAS_FLAG);
		foreground.setColor(getResources().getColor(R.color.foreground));
		foreground.setStyle(Style.FILL);
		foreground.setTextSize(tileHeight * 0.75f);
		foreground.setTextScaleX(tileWidth / tileHeight);
		foreground.setTextAlign(Paint.Align.CENTER);
		
		FontMetrics fm = foreground.getFontMetrics();
		float x = tileWidth / 2;
		float y = tileHeight / 2 - (fm.ascent + fm.descent) / 2;
		for (int i = 0; i < 9; i++)
		{
			for (int j = 0; j < 9; j++)
			{
				canvas.drawText(Integer.toString(i), i * tileWidth + x, j * tileHeight + y, foreground);
			}
		}
		
		Paint selected = new Paint();
		selected.setColor(getResources().getColor(R.color.selected));
		canvas.drawRect(selRect, selected);
	}
	
	private void getRect(int x, int y, Rect rect)
	{
		rect.set((int)(x * tileWidth), (int)(y * tileHeight), (int)(x * tileWidth + tileWidth), (int)(y * tileHeight + tileHeight));
	}
	
	private void select(int x, int y)
	{
		invalidate(selRect);
		selX = Math.min(Math.max(x, 0), 8);
		selY = Math.min(Math.max(y, 0), 8);
		getRect(selX, selY, selRect);
		invalidate(selRect);
	}
}
